#include "e2d/core/trans/TransformHandler.h"
#include "e2d/core/trans/LayoutGrid.h"
#include "e2d/core/trans/Animator.h"
#include "e2d/core/trans/AnimationClip.h"
#include "e2d/core/Entity.h"


void e2d::TransformHandler::OnLoad()
{
	LoadView<e2d::TransformNode>();
	LoadView<e2d::LayoutGrid>();

	LoadView<e2d::AnimationClip>();
	LoadView<e2d::Animator>();
}

void e2d::TransformHandler::OnUpdate()
{
	for (auto child : m_Scene->m_Entities)
	{
		UpdateTransform(child.get(), glm::mat4(1.0f));
	}

	UpdateView<e2d::TransformNode>();
	UpdateView<e2d::LayoutGrid>();

	UpdateView<e2d::AnimationClip>();
	UpdateView<e2d::Animator>();
}


void e2d::TransformHandler::UpdateTransform(e2d::Entity* entity, const glm::mat4& parentMatrix)
{
	if (entity->HasComponent<e2d::TransformNode>())
	{
		auto& transformNode = entity->Get<e2d::TransformNode>();
		glm::mat4 localMatrix = transformNode.m_Local.GetWorld();

		glm::mat4 worldMatrix = parentMatrix * localMatrix;

		transformNode.m_World.CreateFrom(worldMatrix);

		for (auto child : entity->m_Children)
		{
			UpdateTransform(child.get(), worldMatrix);
		}
	}
}


void e2d::TransformHandler::OnUpdateRuntime()
{
	UpdateViewRuntime<e2d::TransformNode>();
	UpdateViewRuntime<e2d::LayoutGrid>();

	UpdateViewRuntime<e2d::AnimationClip>();
	UpdateViewRuntime<e2d::Animator>();
}

void e2d::TransformHandler::OnDestory()
{
	DestoryView<e2d::TransformNode>();
	DestoryView<e2d::LayoutGrid>();

	DestoryView<e2d::AnimationClip>();
	DestoryView<e2d::Animator>();
}
